// Licensed to Elasticsearch B.V under one or more agreements.
// Elasticsearch B.V licenses this file to you under the Apache 2.0 License.
// See the LICENSE file in the project root for more information.
//
// ███╗   ██╗ ██████╗ ████████╗██╗ ██████╗███████╗
// ████╗  ██║██╔═══██╗╚══██╔══╝██║██╔════╝██╔════╝
// ██╔██╗ ██║██║   ██║   ██║   ██║██║     █████╗
// ██║╚██╗██║██║   ██║   ██║   ██║██║     ██╔══╝
// ██║ ╚████║╚██████╔╝   ██║   ██║╚██████╗███████╗
// ╚═╝  ╚═══╝ ╚═════╝    ╚═╝   ╚═╝ ╚═════╝╚══════╝
// ------------------------------------------------
//
// This file is automatically generated.
// Please do not edit these files manually.
//
// ------------------------------------------------

#nullable restore

using Elastic.Clients.Elasticsearch.Fluent;
using Elastic.Clients.Elasticsearch.Requests;
using Elastic.Clients.Elasticsearch.Serialization;
using Elastic.Transport;
using Elastic.Transport.Extensions;
using System;
using System.Collections.Generic;
using System.Linq.Expressions;
using System.Text.Json;
using System.Text.Json.Serialization;

namespace Elastic.Clients.Elasticsearch.MachineLearning;

public sealed partial class PutDatafeedRequestParameters : RequestParameters
{
	/// <summary>
	/// <para>
	/// If true, wildcard indices expressions that resolve into no concrete indices are ignored. This includes the <c>_all</c>
	/// string or when no indices are specified.
	/// </para>
	/// </summary>
	public bool? AllowNoIndices { get => Q<bool?>("allow_no_indices"); set => Q("allow_no_indices", value); }

	/// <summary>
	/// <para>
	/// Type of index that wildcard patterns can match. If the request can target data streams, this argument determines
	/// whether wildcard expressions match hidden data streams. Supports comma-separated values.
	/// </para>
	/// </summary>
	public ICollection<Elastic.Clients.Elasticsearch.ExpandWildcard>? ExpandWildcards { get => Q<ICollection<Elastic.Clients.Elasticsearch.ExpandWildcard>?>("expand_wildcards"); set => Q("expand_wildcards", value); }

	/// <summary>
	/// <para>
	/// If true, unavailable indices (missing or closed) are ignored.
	/// </para>
	/// </summary>
	public bool? IgnoreUnavailable { get => Q<bool?>("ignore_unavailable"); set => Q("ignore_unavailable", value); }
}

internal sealed partial class PutDatafeedRequestConverter : JsonConverter<PutDatafeedRequest>
{
	public override PutDatafeedRequest Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options)
	{
		if (reader.TokenType != JsonTokenType.StartObject)
			throw new JsonException("Unexpected JSON detected.");
		var variant = new PutDatafeedRequest();
		while (reader.Read() && reader.TokenType != JsonTokenType.EndObject)
		{
			if (reader.TokenType == JsonTokenType.PropertyName)
			{
				var property = reader.GetString();
				if (property == "aggregations")
				{
					variant.Aggregations = JsonSerializer.Deserialize<IDictionary<string, Elastic.Clients.Elasticsearch.Aggregations.Aggregation>?>(ref reader, options);
					continue;
				}

				if (property == "chunking_config")
				{
					variant.ChunkingConfig = JsonSerializer.Deserialize<Elastic.Clients.Elasticsearch.MachineLearning.ChunkingConfig?>(ref reader, options);
					continue;
				}

				if (property == "delayed_data_check_config")
				{
					variant.DelayedDataCheckConfig = JsonSerializer.Deserialize<Elastic.Clients.Elasticsearch.MachineLearning.DelayedDataCheckConfig?>(ref reader, options);
					continue;
				}

				if (property == "frequency")
				{
					variant.Frequency = JsonSerializer.Deserialize<Elastic.Clients.Elasticsearch.Duration?>(ref reader, options);
					continue;
				}

				if (property == "headers")
				{
					variant.Headers = JsonSerializer.Deserialize<IDictionary<string, Union<string, ICollection<string>>>?>(ref reader, options);
					continue;
				}

				if (property == "indices" || property == "indexes")
				{
					variant.Indices = JsonSerializer.Deserialize<Elastic.Clients.Elasticsearch.Indices?>(ref reader, options);
					continue;
				}

				if (property == "indices_options")
				{
					variant.IndicesOptions = JsonSerializer.Deserialize<Elastic.Clients.Elasticsearch.IndicesOptions?>(ref reader, options);
					continue;
				}

				if (property == "job_id")
				{
					variant.JobId = JsonSerializer.Deserialize<Elastic.Clients.Elasticsearch.Id?>(ref reader, options);
					continue;
				}

				if (property == "max_empty_searches")
				{
					variant.MaxEmptySearches = JsonSerializer.Deserialize<int?>(ref reader, options);
					continue;
				}

				if (property == "query")
				{
					variant.Query = JsonSerializer.Deserialize<Elastic.Clients.Elasticsearch.QueryDsl.Query?>(ref reader, options);
					continue;
				}

				if (property == "query_delay")
				{
					variant.QueryDelay = JsonSerializer.Deserialize<Elastic.Clients.Elasticsearch.Duration?>(ref reader, options);
					continue;
				}

				if (property == "runtime_mappings")
				{
					variant.RuntimeMappings = JsonSerializer.Deserialize<IDictionary<Elastic.Clients.Elasticsearch.Field, Elastic.Clients.Elasticsearch.Mapping.RuntimeField>?>(ref reader, options);
					continue;
				}

				if (property == "script_fields")
				{
					variant.ScriptFields = JsonSerializer.Deserialize<IDictionary<string, Elastic.Clients.Elasticsearch.ScriptField>?>(ref reader, options);
					continue;
				}

				if (property == "scroll_size")
				{
					variant.ScrollSize = JsonSerializer.Deserialize<int?>(ref reader, options);
					continue;
				}
			}
		}

		return variant;
	}

	public override void Write(Utf8JsonWriter writer, PutDatafeedRequest value, JsonSerializerOptions options)
	{
		writer.WriteStartObject();
		if (value.Aggregations is not null)
		{
			writer.WritePropertyName("aggregations");
			JsonSerializer.Serialize(writer, value.Aggregations, options);
		}

		if (value.ChunkingConfig is not null)
		{
			writer.WritePropertyName("chunking_config");
			JsonSerializer.Serialize(writer, value.ChunkingConfig, options);
		}

		if (value.DelayedDataCheckConfig is not null)
		{
			writer.WritePropertyName("delayed_data_check_config");
			JsonSerializer.Serialize(writer, value.DelayedDataCheckConfig, options);
		}

		if (value.Frequency is not null)
		{
			writer.WritePropertyName("frequency");
			JsonSerializer.Serialize(writer, value.Frequency, options);
		}

		if (value.Headers is not null)
		{
			writer.WritePropertyName("headers");
			JsonSerializer.Serialize(writer, value.Headers, options);
		}

		if (value.Indices is not null)
		{
			writer.WritePropertyName("indices");
			JsonSerializer.Serialize(writer, value.Indices, options);
		}

		if (value.IndicesOptions is not null)
		{
			writer.WritePropertyName("indices_options");
			JsonSerializer.Serialize(writer, value.IndicesOptions, options);
		}

		if (value.JobId is not null)
		{
			writer.WritePropertyName("job_id");
			JsonSerializer.Serialize(writer, value.JobId, options);
		}

		if (value.MaxEmptySearches.HasValue)
		{
			writer.WritePropertyName("max_empty_searches");
			writer.WriteNumberValue(value.MaxEmptySearches.Value);
		}

		if (value.Query is not null)
		{
			writer.WritePropertyName("query");
			JsonSerializer.Serialize(writer, value.Query, options);
		}

		if (value.QueryDelay is not null)
		{
			writer.WritePropertyName("query_delay");
			JsonSerializer.Serialize(writer, value.QueryDelay, options);
		}

		if (value.RuntimeMappings is not null)
		{
			writer.WritePropertyName("runtime_mappings");
			JsonSerializer.Serialize(writer, value.RuntimeMappings, options);
		}

		if (value.ScriptFields is not null)
		{
			writer.WritePropertyName("script_fields");
			JsonSerializer.Serialize(writer, value.ScriptFields, options);
		}

		if (value.ScrollSize.HasValue)
		{
			writer.WritePropertyName("scroll_size");
			writer.WriteNumberValue(value.ScrollSize.Value);
		}

		writer.WriteEndObject();
	}
}

/// <summary>
/// <para>
/// Create a datafeed.
/// Datafeeds retrieve data from Elasticsearch for analysis by an anomaly detection job.
/// You can associate only one datafeed with each anomaly detection job.
/// The datafeed contains a query that runs at a defined interval (<c>frequency</c>).
/// If you are concerned about delayed data, you can add a delay (<c>query_delay') at each interval. When Elasticsearch security features are enabled, your datafeed remembers which roles the user who created it had at the time of creation and runs the query using those same roles. If you provide secondary authorization headers, those credentials are used instead. You must use Kibana, this API, or the create anomaly detection jobs API to create a datafeed. Do not add a datafeed directly to the </c>.ml-config<c>index. Do not give users</c>write<c>privileges on the</c>.ml-config` index.
/// </para>
/// </summary>
[JsonConverter(typeof(PutDatafeedRequestConverter))]
public sealed partial class PutDatafeedRequest : PlainRequest<PutDatafeedRequestParameters>
{
	public PutDatafeedRequest(Elastic.Clients.Elasticsearch.Id datafeedId) : base(r => r.Required("datafeed_id", datafeedId))
	{
	}

	public PutDatafeedRequest()
	{
	}

	internal override ApiUrls ApiUrls => ApiUrlLookup.MachineLearningPutDatafeed;

	protected override HttpMethod StaticHttpMethod => HttpMethod.PUT;

	internal override bool SupportsBody => true;

	internal override string OperationName => "ml.put_datafeed";

	/// <summary>
	/// <para>
	/// If true, wildcard indices expressions that resolve into no concrete indices are ignored. This includes the <c>_all</c>
	/// string or when no indices are specified.
	/// </para>
	/// </summary>
	[JsonIgnore]
	public bool? AllowNoIndices { get => Q<bool?>("allow_no_indices"); set => Q("allow_no_indices", value); }

	/// <summary>
	/// <para>
	/// Type of index that wildcard patterns can match. If the request can target data streams, this argument determines
	/// whether wildcard expressions match hidden data streams. Supports comma-separated values.
	/// </para>
	/// </summary>
	[JsonIgnore]
	public ICollection<Elastic.Clients.Elasticsearch.ExpandWildcard>? ExpandWildcards { get => Q<ICollection<Elastic.Clients.Elasticsearch.ExpandWildcard>?>("expand_wildcards"); set => Q("expand_wildcards", value); }

	/// <summary>
	/// <para>
	/// If true, unavailable indices (missing or closed) are ignored.
	/// </para>
	/// </summary>
	[JsonIgnore]
	public bool? IgnoreUnavailable { get => Q<bool?>("ignore_unavailable"); set => Q("ignore_unavailable", value); }

	/// <summary>
	/// <para>
	/// If set, the datafeed performs aggregation searches.
	/// Support for aggregations is limited and should be used only with low cardinality data.
	/// </para>
	/// </summary>
	[JsonInclude, JsonPropertyName("aggregations")]
	public IDictionary<string, Elastic.Clients.Elasticsearch.Aggregations.Aggregation>? Aggregations { get; set; }

	/// <summary>
	/// <para>
	/// Datafeeds might be required to search over long time periods, for several months or years.
	/// This search is split into time chunks in order to ensure the load on Elasticsearch is managed.
	/// Chunking configuration controls how the size of these time chunks are calculated;
	/// it is an advanced configuration option.
	/// </para>
	/// </summary>
	[JsonInclude, JsonPropertyName("chunking_config")]
	public Elastic.Clients.Elasticsearch.MachineLearning.ChunkingConfig? ChunkingConfig { get; set; }

	/// <summary>
	/// <para>
	/// Specifies whether the datafeed checks for missing data and the size of the window.
	/// The datafeed can optionally search over indices that have already been read in an effort to determine whether
	/// any data has subsequently been added to the index. If missing data is found, it is a good indication that the
	/// <c>query_delay</c> is set too low and the data is being indexed after the datafeed has passed that moment in time.
	/// This check runs only on real-time datafeeds.
	/// </para>
	/// </summary>
	[JsonInclude, JsonPropertyName("delayed_data_check_config")]
	public Elastic.Clients.Elasticsearch.MachineLearning.DelayedDataCheckConfig? DelayedDataCheckConfig { get; set; }

	/// <summary>
	/// <para>
	/// The interval at which scheduled queries are made while the datafeed runs in real time.
	/// The default value is either the bucket span for short bucket spans, or, for longer bucket spans, a sensible
	/// fraction of the bucket span. When <c>frequency</c> is shorter than the bucket span, interim results for the last
	/// (partial) bucket are written then eventually overwritten by the full bucket results. If the datafeed uses
	/// aggregations, this value must be divisible by the interval of the date histogram aggregation.
	/// </para>
	/// </summary>
	[JsonInclude, JsonPropertyName("frequency")]
	public Elastic.Clients.Elasticsearch.Duration? Frequency { get; set; }
	[JsonInclude, JsonPropertyName("headers")]
	public IDictionary<string, Union<string, ICollection<string>>>? Headers { get; set; }

	/// <summary>
	/// <para>
	/// An array of index names. Wildcards are supported. If any of the indices are in remote clusters, the machine
	/// learning nodes must have the <c>remote_cluster_client</c> role.
	/// </para>
	/// </summary>
	[JsonInclude, JsonPropertyName("indices")]
	public Elastic.Clients.Elasticsearch.Indices? Indices { get; set; }

	/// <summary>
	/// <para>
	/// Specifies index expansion options that are used during search
	/// </para>
	/// </summary>
	[JsonInclude, JsonPropertyName("indices_options")]
	public Elastic.Clients.Elasticsearch.IndicesOptions? IndicesOptions { get; set; }

	/// <summary>
	/// <para>
	/// Identifier for the anomaly detection job.
	/// </para>
	/// </summary>
	[JsonInclude, JsonPropertyName("job_id")]
	public Elastic.Clients.Elasticsearch.Id? JobId { get; set; }

	/// <summary>
	/// <para>
	/// If a real-time datafeed has never seen any data (including during any initial training period), it automatically
	/// stops and closes the associated job after this many real-time searches return no documents. In other words,
	/// it stops after <c>frequency</c> times <c>max_empty_searches</c> of real-time operation. If not set, a datafeed with no
	/// end time that sees no data remains started until it is explicitly stopped. By default, it is not set.
	/// </para>
	/// </summary>
	[JsonInclude, JsonPropertyName("max_empty_searches")]
	public int? MaxEmptySearches { get; set; }

	/// <summary>
	/// <para>
	/// The Elasticsearch query domain-specific language (DSL). This value corresponds to the query object in an
	/// Elasticsearch search POST body. All the options that are supported by Elasticsearch can be used, as this
	/// object is passed verbatim to Elasticsearch.
	/// </para>
	/// </summary>
	[JsonInclude, JsonPropertyName("query")]
	public Elastic.Clients.Elasticsearch.QueryDsl.Query? Query { get; set; }

	/// <summary>
	/// <para>
	/// The number of seconds behind real time that data is queried. For example, if data from 10:04 a.m. might
	/// not be searchable in Elasticsearch until 10:06 a.m., set this property to 120 seconds. The default
	/// value is randomly selected between <c>60s</c> and <c>120s</c>. This randomness improves the query performance
	/// when there are multiple jobs running on the same node.
	/// </para>
	/// </summary>
	[JsonInclude, JsonPropertyName("query_delay")]
	public Elastic.Clients.Elasticsearch.Duration? QueryDelay { get; set; }

	/// <summary>
	/// <para>
	/// Specifies runtime fields for the datafeed search.
	/// </para>
	/// </summary>
	[JsonInclude, JsonPropertyName("runtime_mappings")]
	public IDictionary<Elastic.Clients.Elasticsearch.Field, Elastic.Clients.Elasticsearch.Mapping.RuntimeField>? RuntimeMappings { get; set; }

	/// <summary>
	/// <para>
	/// Specifies scripts that evaluate custom expressions and returns script fields to the datafeed.
	/// The detector configuration objects in a job can contain functions that use these script fields.
	/// </para>
	/// </summary>
	[JsonInclude, JsonPropertyName("script_fields")]
	public IDictionary<string, Elastic.Clients.Elasticsearch.ScriptField>? ScriptFields { get; set; }

	/// <summary>
	/// <para>
	/// The size parameter that is used in Elasticsearch searches when the datafeed does not use aggregations.
	/// The maximum value is the value of <c>index.max_result_window</c>, which is 10,000 by default.
	/// </para>
	/// </summary>
	[JsonInclude, JsonPropertyName("scroll_size")]
	public int? ScrollSize { get; set; }
}

/// <summary>
/// <para>
/// Create a datafeed.
/// Datafeeds retrieve data from Elasticsearch for analysis by an anomaly detection job.
/// You can associate only one datafeed with each anomaly detection job.
/// The datafeed contains a query that runs at a defined interval (<c>frequency</c>).
/// If you are concerned about delayed data, you can add a delay (<c>query_delay') at each interval. When Elasticsearch security features are enabled, your datafeed remembers which roles the user who created it had at the time of creation and runs the query using those same roles. If you provide secondary authorization headers, those credentials are used instead. You must use Kibana, this API, or the create anomaly detection jobs API to create a datafeed. Do not add a datafeed directly to the </c>.ml-config<c>index. Do not give users</c>write<c>privileges on the</c>.ml-config` index.
/// </para>
/// </summary>
public sealed partial class PutDatafeedRequestDescriptor<TDocument> : RequestDescriptor<PutDatafeedRequestDescriptor<TDocument>, PutDatafeedRequestParameters>
{
	internal PutDatafeedRequestDescriptor(Action<PutDatafeedRequestDescriptor<TDocument>> configure) => configure.Invoke(this);

	public PutDatafeedRequestDescriptor(Elastic.Clients.Elasticsearch.Id datafeedId) : base(r => r.Required("datafeed_id", datafeedId))
	{
	}

	internal override ApiUrls ApiUrls => ApiUrlLookup.MachineLearningPutDatafeed;

	protected override HttpMethod StaticHttpMethod => HttpMethod.PUT;

	internal override bool SupportsBody => true;

	internal override string OperationName => "ml.put_datafeed";

	public PutDatafeedRequestDescriptor<TDocument> AllowNoIndices(bool? allowNoIndices = true) => Qs("allow_no_indices", allowNoIndices);
	public PutDatafeedRequestDescriptor<TDocument> ExpandWildcards(ICollection<Elastic.Clients.Elasticsearch.ExpandWildcard>? expandWildcards) => Qs("expand_wildcards", expandWildcards);
	public PutDatafeedRequestDescriptor<TDocument> IgnoreUnavailable(bool? ignoreUnavailable = true) => Qs("ignore_unavailable", ignoreUnavailable);

	public PutDatafeedRequestDescriptor<TDocument> DatafeedId(Elastic.Clients.Elasticsearch.Id datafeedId)
	{
		RouteValues.Required("datafeed_id", datafeedId);
		return Self;
	}

	private IDictionary<string, Elastic.Clients.Elasticsearch.Aggregations.AggregationDescriptor<TDocument>> AggregationsValue { get; set; }
	private Elastic.Clients.Elasticsearch.MachineLearning.ChunkingConfig? ChunkingConfigValue { get; set; }
	private Elastic.Clients.Elasticsearch.MachineLearning.ChunkingConfigDescriptor ChunkingConfigDescriptor { get; set; }
	private Action<Elastic.Clients.Elasticsearch.MachineLearning.ChunkingConfigDescriptor> ChunkingConfigDescriptorAction { get; set; }
	private Elastic.Clients.Elasticsearch.MachineLearning.DelayedDataCheckConfig? DelayedDataCheckConfigValue { get; set; }
	private Elastic.Clients.Elasticsearch.MachineLearning.DelayedDataCheckConfigDescriptor DelayedDataCheckConfigDescriptor { get; set; }
	private Action<Elastic.Clients.Elasticsearch.MachineLearning.DelayedDataCheckConfigDescriptor> DelayedDataCheckConfigDescriptorAction { get; set; }
	private Elastic.Clients.Elasticsearch.Duration? FrequencyValue { get; set; }
	private IDictionary<string, Union<string, ICollection<string>>>? HeadersValue { get; set; }
	private Elastic.Clients.Elasticsearch.Indices? IndicesValue { get; set; }
	private Elastic.Clients.Elasticsearch.IndicesOptions? IndicesOptionsValue { get; set; }
	private Elastic.Clients.Elasticsearch.IndicesOptionsDescriptor IndicesOptionsDescriptor { get; set; }
	private Action<Elastic.Clients.Elasticsearch.IndicesOptionsDescriptor> IndicesOptionsDescriptorAction { get; set; }
	private Elastic.Clients.Elasticsearch.Id? JobIdValue { get; set; }
	private int? MaxEmptySearchesValue { get; set; }
	private Elastic.Clients.Elasticsearch.QueryDsl.Query? QueryValue { get; set; }
	private Elastic.Clients.Elasticsearch.QueryDsl.QueryDescriptor<TDocument> QueryDescriptor { get; set; }
	private Action<Elastic.Clients.Elasticsearch.QueryDsl.QueryDescriptor<TDocument>> QueryDescriptorAction { get; set; }
	private Elastic.Clients.Elasticsearch.Duration? QueryDelayValue { get; set; }
	private IDictionary<Elastic.Clients.Elasticsearch.Field, Elastic.Clients.Elasticsearch.Mapping.RuntimeFieldDescriptor<TDocument>> RuntimeMappingsValue { get; set; }
	private IDictionary<string, Elastic.Clients.Elasticsearch.ScriptFieldDescriptor> ScriptFieldsValue { get; set; }
	private int? ScrollSizeValue { get; set; }

	/// <summary>
	/// <para>
	/// If set, the datafeed performs aggregation searches.
	/// Support for aggregations is limited and should be used only with low cardinality data.
	/// </para>
	/// </summary>
	public PutDatafeedRequestDescriptor<TDocument> Aggregations(Func<FluentDescriptorDictionary<string, Elastic.Clients.Elasticsearch.Aggregations.AggregationDescriptor<TDocument>>, FluentDescriptorDictionary<string, Elastic.Clients.Elasticsearch.Aggregations.AggregationDescriptor<TDocument>>> selector)
	{
		AggregationsValue = selector?.Invoke(new FluentDescriptorDictionary<string, Elastic.Clients.Elasticsearch.Aggregations.AggregationDescriptor<TDocument>>());
		return Self;
	}

	/// <summary>
	/// <para>
	/// Datafeeds might be required to search over long time periods, for several months or years.
	/// This search is split into time chunks in order to ensure the load on Elasticsearch is managed.
	/// Chunking configuration controls how the size of these time chunks are calculated;
	/// it is an advanced configuration option.
	/// </para>
	/// </summary>
	public PutDatafeedRequestDescriptor<TDocument> ChunkingConfig(Elastic.Clients.Elasticsearch.MachineLearning.ChunkingConfig? chunkingConfig)
	{
		ChunkingConfigDescriptor = null;
		ChunkingConfigDescriptorAction = null;
		ChunkingConfigValue = chunkingConfig;
		return Self;
	}

	public PutDatafeedRequestDescriptor<TDocument> ChunkingConfig(Elastic.Clients.Elasticsearch.MachineLearning.ChunkingConfigDescriptor descriptor)
	{
		ChunkingConfigValue = null;
		ChunkingConfigDescriptorAction = null;
		ChunkingConfigDescriptor = descriptor;
		return Self;
	}

	public PutDatafeedRequestDescriptor<TDocument> ChunkingConfig(Action<Elastic.Clients.Elasticsearch.MachineLearning.ChunkingConfigDescriptor> configure)
	{
		ChunkingConfigValue = null;
		ChunkingConfigDescriptor = null;
		ChunkingConfigDescriptorAction = configure;
		return Self;
	}

	/// <summary>
	/// <para>
	/// Specifies whether the datafeed checks for missing data and the size of the window.
	/// The datafeed can optionally search over indices that have already been read in an effort to determine whether
	/// any data has subsequently been added to the index. If missing data is found, it is a good indication that the
	/// <c>query_delay</c> is set too low and the data is being indexed after the datafeed has passed that moment in time.
	/// This check runs only on real-time datafeeds.
	/// </para>
	/// </summary>
	public PutDatafeedRequestDescriptor<TDocument> DelayedDataCheckConfig(Elastic.Clients.Elasticsearch.MachineLearning.DelayedDataCheckConfig? delayedDataCheckConfig)
	{
		DelayedDataCheckConfigDescriptor = null;
		DelayedDataCheckConfigDescriptorAction = null;
		DelayedDataCheckConfigValue = delayedDataCheckConfig;
		return Self;
	}

	public PutDatafeedRequestDescriptor<TDocument> DelayedDataCheckConfig(Elastic.Clients.Elasticsearch.MachineLearning.DelayedDataCheckConfigDescriptor descriptor)
	{
		DelayedDataCheckConfigValue = null;
		DelayedDataCheckConfigDescriptorAction = null;
		DelayedDataCheckConfigDescriptor = descriptor;
		return Self;
	}

	public PutDatafeedRequestDescriptor<TDocument> DelayedDataCheckConfig(Action<Elastic.Clients.Elasticsearch.MachineLearning.DelayedDataCheckConfigDescriptor> configure)
	{
		DelayedDataCheckConfigValue = null;
		DelayedDataCheckConfigDescriptor = null;
		DelayedDataCheckConfigDescriptorAction = configure;
		return Self;
	}

	/// <summary>
	/// <para>
	/// The interval at which scheduled queries are made while the datafeed runs in real time.
	/// The default value is either the bucket span for short bucket spans, or, for longer bucket spans, a sensible
	/// fraction of the bucket span. When <c>frequency</c> is shorter than the bucket span, interim results for the last
	/// (partial) bucket are written then eventually overwritten by the full bucket results. If the datafeed uses
	/// aggregations, this value must be divisible by the interval of the date histogram aggregation.
	/// </para>
	/// </summary>
	public PutDatafeedRequestDescriptor<TDocument> Frequency(Elastic.Clients.Elasticsearch.Duration? frequency)
	{
		FrequencyValue = frequency;
		return Self;
	}

	public PutDatafeedRequestDescriptor<TDocument> Headers(Func<FluentDictionary<string, Union<string, ICollection<string>>>, FluentDictionary<string, Union<string, ICollection<string>>>> selector)
	{
		HeadersValue = selector?.Invoke(new FluentDictionary<string, Union<string, ICollection<string>>>());
		return Self;
	}

	/// <summary>
	/// <para>
	/// An array of index names. Wildcards are supported. If any of the indices are in remote clusters, the machine
	/// learning nodes must have the <c>remote_cluster_client</c> role.
	/// </para>
	/// </summary>
	public PutDatafeedRequestDescriptor<TDocument> Indices(Elastic.Clients.Elasticsearch.Indices? indices)
	{
		IndicesValue = indices;
		return Self;
	}

	/// <summary>
	/// <para>
	/// Specifies index expansion options that are used during search
	/// </para>
	/// </summary>
	public PutDatafeedRequestDescriptor<TDocument> IndicesOptions(Elastic.Clients.Elasticsearch.IndicesOptions? indicesOptions)
	{
		IndicesOptionsDescriptor = null;
		IndicesOptionsDescriptorAction = null;
		IndicesOptionsValue = indicesOptions;
		return Self;
	}

	public PutDatafeedRequestDescriptor<TDocument> IndicesOptions(Elastic.Clients.Elasticsearch.IndicesOptionsDescriptor descriptor)
	{
		IndicesOptionsValue = null;
		IndicesOptionsDescriptorAction = null;
		IndicesOptionsDescriptor = descriptor;
		return Self;
	}

	public PutDatafeedRequestDescriptor<TDocument> IndicesOptions(Action<Elastic.Clients.Elasticsearch.IndicesOptionsDescriptor> configure)
	{
		IndicesOptionsValue = null;
		IndicesOptionsDescriptor = null;
		IndicesOptionsDescriptorAction = configure;
		return Self;
	}

	/// <summary>
	/// <para>
	/// Identifier for the anomaly detection job.
	/// </para>
	/// </summary>
	public PutDatafeedRequestDescriptor<TDocument> JobId(Elastic.Clients.Elasticsearch.Id? jobId)
	{
		JobIdValue = jobId;
		return Self;
	}

	/// <summary>
	/// <para>
	/// If a real-time datafeed has never seen any data (including during any initial training period), it automatically
	/// stops and closes the associated job after this many real-time searches return no documents. In other words,
	/// it stops after <c>frequency</c> times <c>max_empty_searches</c> of real-time operation. If not set, a datafeed with no
	/// end time that sees no data remains started until it is explicitly stopped. By default, it is not set.
	/// </para>
	/// </summary>
	public PutDatafeedRequestDescriptor<TDocument> MaxEmptySearches(int? maxEmptySearches)
	{
		MaxEmptySearchesValue = maxEmptySearches;
		return Self;
	}

	/// <summary>
	/// <para>
	/// The Elasticsearch query domain-specific language (DSL). This value corresponds to the query object in an
	/// Elasticsearch search POST body. All the options that are supported by Elasticsearch can be used, as this
	/// object is passed verbatim to Elasticsearch.
	/// </para>
	/// </summary>
	public PutDatafeedRequestDescriptor<TDocument> Query(Elastic.Clients.Elasticsearch.QueryDsl.Query? query)
	{
		QueryDescriptor = null;
		QueryDescriptorAction = null;
		QueryValue = query;
		return Self;
	}

	public PutDatafeedRequestDescriptor<TDocument> Query(Elastic.Clients.Elasticsearch.QueryDsl.QueryDescriptor<TDocument> descriptor)
	{
		QueryValue = null;
		QueryDescriptorAction = null;
		QueryDescriptor = descriptor;
		return Self;
	}

	public PutDatafeedRequestDescriptor<TDocument> Query(Action<Elastic.Clients.Elasticsearch.QueryDsl.QueryDescriptor<TDocument>> configure)
	{
		QueryValue = null;
		QueryDescriptor = null;
		QueryDescriptorAction = configure;
		return Self;
	}

	/// <summary>
	/// <para>
	/// The number of seconds behind real time that data is queried. For example, if data from 10:04 a.m. might
	/// not be searchable in Elasticsearch until 10:06 a.m., set this property to 120 seconds. The default
	/// value is randomly selected between <c>60s</c> and <c>120s</c>. This randomness improves the query performance
	/// when there are multiple jobs running on the same node.
	/// </para>
	/// </summary>
	public PutDatafeedRequestDescriptor<TDocument> QueryDelay(Elastic.Clients.Elasticsearch.Duration? queryDelay)
	{
		QueryDelayValue = queryDelay;
		return Self;
	}

	/// <summary>
	/// <para>
	/// Specifies runtime fields for the datafeed search.
	/// </para>
	/// </summary>
	public PutDatafeedRequestDescriptor<TDocument> RuntimeMappings(Func<FluentDescriptorDictionary<Elastic.Clients.Elasticsearch.Field, Elastic.Clients.Elasticsearch.Mapping.RuntimeFieldDescriptor<TDocument>>, FluentDescriptorDictionary<Elastic.Clients.Elasticsearch.Field, Elastic.Clients.Elasticsearch.Mapping.RuntimeFieldDescriptor<TDocument>>> selector)
	{
		RuntimeMappingsValue = selector?.Invoke(new FluentDescriptorDictionary<Elastic.Clients.Elasticsearch.Field, Elastic.Clients.Elasticsearch.Mapping.RuntimeFieldDescriptor<TDocument>>());
		return Self;
	}

	/// <summary>
	/// <para>
	/// Specifies scripts that evaluate custom expressions and returns script fields to the datafeed.
	/// The detector configuration objects in a job can contain functions that use these script fields.
	/// </para>
	/// </summary>
	public PutDatafeedRequestDescriptor<TDocument> ScriptFields(Func<FluentDescriptorDictionary<string, Elastic.Clients.Elasticsearch.ScriptFieldDescriptor>, FluentDescriptorDictionary<string, Elastic.Clients.Elasticsearch.ScriptFieldDescriptor>> selector)
	{
		ScriptFieldsValue = selector?.Invoke(new FluentDescriptorDictionary<string, Elastic.Clients.Elasticsearch.ScriptFieldDescriptor>());
		return Self;
	}

	/// <summary>
	/// <para>
	/// The size parameter that is used in Elasticsearch searches when the datafeed does not use aggregations.
	/// The maximum value is the value of <c>index.max_result_window</c>, which is 10,000 by default.
	/// </para>
	/// </summary>
	public PutDatafeedRequestDescriptor<TDocument> ScrollSize(int? scrollSize)
	{
		ScrollSizeValue = scrollSize;
		return Self;
	}

	protected override void Serialize(Utf8JsonWriter writer, JsonSerializerOptions options, IElasticsearchClientSettings settings)
	{
		writer.WriteStartObject();
		if (AggregationsValue is not null)
		{
			writer.WritePropertyName("aggregations");
			JsonSerializer.Serialize(writer, AggregationsValue, options);
		}

		if (ChunkingConfigDescriptor is not null)
		{
			writer.WritePropertyName("chunking_config");
			JsonSerializer.Serialize(writer, ChunkingConfigDescriptor, options);
		}
		else if (ChunkingConfigDescriptorAction is not null)
		{
			writer.WritePropertyName("chunking_config");
			JsonSerializer.Serialize(writer, new Elastic.Clients.Elasticsearch.MachineLearning.ChunkingConfigDescriptor(ChunkingConfigDescriptorAction), options);
		}
		else if (ChunkingConfigValue is not null)
		{
			writer.WritePropertyName("chunking_config");
			JsonSerializer.Serialize(writer, ChunkingConfigValue, options);
		}

		if (DelayedDataCheckConfigDescriptor is not null)
		{
			writer.WritePropertyName("delayed_data_check_config");
			JsonSerializer.Serialize(writer, DelayedDataCheckConfigDescriptor, options);
		}
		else if (DelayedDataCheckConfigDescriptorAction is not null)
		{
			writer.WritePropertyName("delayed_data_check_config");
			JsonSerializer.Serialize(writer, new Elastic.Clients.Elasticsearch.MachineLearning.DelayedDataCheckConfigDescriptor(DelayedDataCheckConfigDescriptorAction), options);
		}
		else if (DelayedDataCheckConfigValue is not null)
		{
			writer.WritePropertyName("delayed_data_check_config");
			JsonSerializer.Serialize(writer, DelayedDataCheckConfigValue, options);
		}

		if (FrequencyValue is not null)
		{
			writer.WritePropertyName("frequency");
			JsonSerializer.Serialize(writer, FrequencyValue, options);
		}

		if (HeadersValue is not null)
		{
			writer.WritePropertyName("headers");
			JsonSerializer.Serialize(writer, HeadersValue, options);
		}

		if (IndicesValue is not null)
		{
			writer.WritePropertyName("indices");
			JsonSerializer.Serialize(writer, IndicesValue, options);
		}

		if (IndicesOptionsDescriptor is not null)
		{
			writer.WritePropertyName("indices_options");
			JsonSerializer.Serialize(writer, IndicesOptionsDescriptor, options);
		}
		else if (IndicesOptionsDescriptorAction is not null)
		{
			writer.WritePropertyName("indices_options");
			JsonSerializer.Serialize(writer, new Elastic.Clients.Elasticsearch.IndicesOptionsDescriptor(IndicesOptionsDescriptorAction), options);
		}
		else if (IndicesOptionsValue is not null)
		{
			writer.WritePropertyName("indices_options");
			JsonSerializer.Serialize(writer, IndicesOptionsValue, options);
		}

		if (JobIdValue is not null)
		{
			writer.WritePropertyName("job_id");
			JsonSerializer.Serialize(writer, JobIdValue, options);
		}

		if (MaxEmptySearchesValue.HasValue)
		{
			writer.WritePropertyName("max_empty_searches");
			writer.WriteNumberValue(MaxEmptySearchesValue.Value);
		}

		if (QueryDescriptor is not null)
		{
			writer.WritePropertyName("query");
			JsonSerializer.Serialize(writer, QueryDescriptor, options);
		}
		else if (QueryDescriptorAction is not null)
		{
			writer.WritePropertyName("query");
			JsonSerializer.Serialize(writer, new Elastic.Clients.Elasticsearch.QueryDsl.QueryDescriptor<TDocument>(QueryDescriptorAction), options);
		}
		else if (QueryValue is not null)
		{
			writer.WritePropertyName("query");
			JsonSerializer.Serialize(writer, QueryValue, options);
		}

		if (QueryDelayValue is not null)
		{
			writer.WritePropertyName("query_delay");
			JsonSerializer.Serialize(writer, QueryDelayValue, options);
		}

		if (RuntimeMappingsValue is not null)
		{
			writer.WritePropertyName("runtime_mappings");
			JsonSerializer.Serialize(writer, RuntimeMappingsValue, options);
		}

		if (ScriptFieldsValue is not null)
		{
			writer.WritePropertyName("script_fields");
			JsonSerializer.Serialize(writer, ScriptFieldsValue, options);
		}

		if (ScrollSizeValue.HasValue)
		{
			writer.WritePropertyName("scroll_size");
			writer.WriteNumberValue(ScrollSizeValue.Value);
		}

		writer.WriteEndObject();
	}
}

/// <summary>
/// <para>
/// Create a datafeed.
/// Datafeeds retrieve data from Elasticsearch for analysis by an anomaly detection job.
/// You can associate only one datafeed with each anomaly detection job.
/// The datafeed contains a query that runs at a defined interval (<c>frequency</c>).
/// If you are concerned about delayed data, you can add a delay (<c>query_delay') at each interval. When Elasticsearch security features are enabled, your datafeed remembers which roles the user who created it had at the time of creation and runs the query using those same roles. If you provide secondary authorization headers, those credentials are used instead. You must use Kibana, this API, or the create anomaly detection jobs API to create a datafeed. Do not add a datafeed directly to the </c>.ml-config<c>index. Do not give users</c>write<c>privileges on the</c>.ml-config` index.
/// </para>
/// </summary>
public sealed partial class PutDatafeedRequestDescriptor : RequestDescriptor<PutDatafeedRequestDescriptor, PutDatafeedRequestParameters>
{
	internal PutDatafeedRequestDescriptor(Action<PutDatafeedRequestDescriptor> configure) => configure.Invoke(this);

	public PutDatafeedRequestDescriptor(Elastic.Clients.Elasticsearch.Id datafeedId) : base(r => r.Required("datafeed_id", datafeedId))
	{
	}

	internal override ApiUrls ApiUrls => ApiUrlLookup.MachineLearningPutDatafeed;

	protected override HttpMethod StaticHttpMethod => HttpMethod.PUT;

	internal override bool SupportsBody => true;

	internal override string OperationName => "ml.put_datafeed";

	public PutDatafeedRequestDescriptor AllowNoIndices(bool? allowNoIndices = true) => Qs("allow_no_indices", allowNoIndices);
	public PutDatafeedRequestDescriptor ExpandWildcards(ICollection<Elastic.Clients.Elasticsearch.ExpandWildcard>? expandWildcards) => Qs("expand_wildcards", expandWildcards);
	public PutDatafeedRequestDescriptor IgnoreUnavailable(bool? ignoreUnavailable = true) => Qs("ignore_unavailable", ignoreUnavailable);

	public PutDatafeedRequestDescriptor DatafeedId(Elastic.Clients.Elasticsearch.Id datafeedId)
	{
		RouteValues.Required("datafeed_id", datafeedId);
		return Self;
	}

	private IDictionary<string, Elastic.Clients.Elasticsearch.Aggregations.AggregationDescriptor> AggregationsValue { get; set; }
	private Elastic.Clients.Elasticsearch.MachineLearning.ChunkingConfig? ChunkingConfigValue { get; set; }
	private Elastic.Clients.Elasticsearch.MachineLearning.ChunkingConfigDescriptor ChunkingConfigDescriptor { get; set; }
	private Action<Elastic.Clients.Elasticsearch.MachineLearning.ChunkingConfigDescriptor> ChunkingConfigDescriptorAction { get; set; }
	private Elastic.Clients.Elasticsearch.MachineLearning.DelayedDataCheckConfig? DelayedDataCheckConfigValue { get; set; }
	private Elastic.Clients.Elasticsearch.MachineLearning.DelayedDataCheckConfigDescriptor DelayedDataCheckConfigDescriptor { get; set; }
	private Action<Elastic.Clients.Elasticsearch.MachineLearning.DelayedDataCheckConfigDescriptor> DelayedDataCheckConfigDescriptorAction { get; set; }
	private Elastic.Clients.Elasticsearch.Duration? FrequencyValue { get; set; }
	private IDictionary<string, Union<string, ICollection<string>>>? HeadersValue { get; set; }
	private Elastic.Clients.Elasticsearch.Indices? IndicesValue { get; set; }
	private Elastic.Clients.Elasticsearch.IndicesOptions? IndicesOptionsValue { get; set; }
	private Elastic.Clients.Elasticsearch.IndicesOptionsDescriptor IndicesOptionsDescriptor { get; set; }
	private Action<Elastic.Clients.Elasticsearch.IndicesOptionsDescriptor> IndicesOptionsDescriptorAction { get; set; }
	private Elastic.Clients.Elasticsearch.Id? JobIdValue { get; set; }
	private int? MaxEmptySearchesValue { get; set; }
	private Elastic.Clients.Elasticsearch.QueryDsl.Query? QueryValue { get; set; }
	private Elastic.Clients.Elasticsearch.QueryDsl.QueryDescriptor QueryDescriptor { get; set; }
	private Action<Elastic.Clients.Elasticsearch.QueryDsl.QueryDescriptor> QueryDescriptorAction { get; set; }
	private Elastic.Clients.Elasticsearch.Duration? QueryDelayValue { get; set; }
	private IDictionary<Elastic.Clients.Elasticsearch.Field, Elastic.Clients.Elasticsearch.Mapping.RuntimeFieldDescriptor> RuntimeMappingsValue { get; set; }
	private IDictionary<string, Elastic.Clients.Elasticsearch.ScriptFieldDescriptor> ScriptFieldsValue { get; set; }
	private int? ScrollSizeValue { get; set; }

	/// <summary>
	/// <para>
	/// If set, the datafeed performs aggregation searches.
	/// Support for aggregations is limited and should be used only with low cardinality data.
	/// </para>
	/// </summary>
	public PutDatafeedRequestDescriptor Aggregations(Func<FluentDescriptorDictionary<string, Elastic.Clients.Elasticsearch.Aggregations.AggregationDescriptor>, FluentDescriptorDictionary<string, Elastic.Clients.Elasticsearch.Aggregations.AggregationDescriptor>> selector)
	{
		AggregationsValue = selector?.Invoke(new FluentDescriptorDictionary<string, Elastic.Clients.Elasticsearch.Aggregations.AggregationDescriptor>());
		return Self;
	}

	/// <summary>
	/// <para>
	/// Datafeeds might be required to search over long time periods, for several months or years.
	/// This search is split into time chunks in order to ensure the load on Elasticsearch is managed.
	/// Chunking configuration controls how the size of these time chunks are calculated;
	/// it is an advanced configuration option.
	/// </para>
	/// </summary>
	public PutDatafeedRequestDescriptor ChunkingConfig(Elastic.Clients.Elasticsearch.MachineLearning.ChunkingConfig? chunkingConfig)
	{
		ChunkingConfigDescriptor = null;
		ChunkingConfigDescriptorAction = null;
		ChunkingConfigValue = chunkingConfig;
		return Self;
	}

	public PutDatafeedRequestDescriptor ChunkingConfig(Elastic.Clients.Elasticsearch.MachineLearning.ChunkingConfigDescriptor descriptor)
	{
		ChunkingConfigValue = null;
		ChunkingConfigDescriptorAction = null;
		ChunkingConfigDescriptor = descriptor;
		return Self;
	}

	public PutDatafeedRequestDescriptor ChunkingConfig(Action<Elastic.Clients.Elasticsearch.MachineLearning.ChunkingConfigDescriptor> configure)
	{
		ChunkingConfigValue = null;
		ChunkingConfigDescriptor = null;
		ChunkingConfigDescriptorAction = configure;
		return Self;
	}

	/// <summary>
	/// <para>
	/// Specifies whether the datafeed checks for missing data and the size of the window.
	/// The datafeed can optionally search over indices that have already been read in an effort to determine whether
	/// any data has subsequently been added to the index. If missing data is found, it is a good indication that the
	/// <c>query_delay</c> is set too low and the data is being indexed after the datafeed has passed that moment in time.
	/// This check runs only on real-time datafeeds.
	/// </para>
	/// </summary>
	public PutDatafeedRequestDescriptor DelayedDataCheckConfig(Elastic.Clients.Elasticsearch.MachineLearning.DelayedDataCheckConfig? delayedDataCheckConfig)
	{
		DelayedDataCheckConfigDescriptor = null;
		DelayedDataCheckConfigDescriptorAction = null;
		DelayedDataCheckConfigValue = delayedDataCheckConfig;
		return Self;
	}

	public PutDatafeedRequestDescriptor DelayedDataCheckConfig(Elastic.Clients.Elasticsearch.MachineLearning.DelayedDataCheckConfigDescriptor descriptor)
	{
		DelayedDataCheckConfigValue = null;
		DelayedDataCheckConfigDescriptorAction = null;
		DelayedDataCheckConfigDescriptor = descriptor;
		return Self;
	}

	public PutDatafeedRequestDescriptor DelayedDataCheckConfig(Action<Elastic.Clients.Elasticsearch.MachineLearning.DelayedDataCheckConfigDescriptor> configure)
	{
		DelayedDataCheckConfigValue = null;
		DelayedDataCheckConfigDescriptor = null;
		DelayedDataCheckConfigDescriptorAction = configure;
		return Self;
	}

	/// <summary>
	/// <para>
	/// The interval at which scheduled queries are made while the datafeed runs in real time.
	/// The default value is either the bucket span for short bucket spans, or, for longer bucket spans, a sensible
	/// fraction of the bucket span. When <c>frequency</c> is shorter than the bucket span, interim results for the last
	/// (partial) bucket are written then eventually overwritten by the full bucket results. If the datafeed uses
	/// aggregations, this value must be divisible by the interval of the date histogram aggregation.
	/// </para>
	/// </summary>
	public PutDatafeedRequestDescriptor Frequency(Elastic.Clients.Elasticsearch.Duration? frequency)
	{
		FrequencyValue = frequency;
		return Self;
	}

	public PutDatafeedRequestDescriptor Headers(Func<FluentDictionary<string, Union<string, ICollection<string>>>, FluentDictionary<string, Union<string, ICollection<string>>>> selector)
	{
		HeadersValue = selector?.Invoke(new FluentDictionary<string, Union<string, ICollection<string>>>());
		return Self;
	}

	/// <summary>
	/// <para>
	/// An array of index names. Wildcards are supported. If any of the indices are in remote clusters, the machine
	/// learning nodes must have the <c>remote_cluster_client</c> role.
	/// </para>
	/// </summary>
	public PutDatafeedRequestDescriptor Indices(Elastic.Clients.Elasticsearch.Indices? indices)
	{
		IndicesValue = indices;
		return Self;
	}

	/// <summary>
	/// <para>
	/// Specifies index expansion options that are used during search
	/// </para>
	/// </summary>
	public PutDatafeedRequestDescriptor IndicesOptions(Elastic.Clients.Elasticsearch.IndicesOptions? indicesOptions)
	{
		IndicesOptionsDescriptor = null;
		IndicesOptionsDescriptorAction = null;
		IndicesOptionsValue = indicesOptions;
		return Self;
	}

	public PutDatafeedRequestDescriptor IndicesOptions(Elastic.Clients.Elasticsearch.IndicesOptionsDescriptor descriptor)
	{
		IndicesOptionsValue = null;
		IndicesOptionsDescriptorAction = null;
		IndicesOptionsDescriptor = descriptor;
		return Self;
	}

	public PutDatafeedRequestDescriptor IndicesOptions(Action<Elastic.Clients.Elasticsearch.IndicesOptionsDescriptor> configure)
	{
		IndicesOptionsValue = null;
		IndicesOptionsDescriptor = null;
		IndicesOptionsDescriptorAction = configure;
		return Self;
	}

	/// <summary>
	/// <para>
	/// Identifier for the anomaly detection job.
	/// </para>
	/// </summary>
	public PutDatafeedRequestDescriptor JobId(Elastic.Clients.Elasticsearch.Id? jobId)
	{
		JobIdValue = jobId;
		return Self;
	}

	/// <summary>
	/// <para>
	/// If a real-time datafeed has never seen any data (including during any initial training period), it automatically
	/// stops and closes the associated job after this many real-time searches return no documents. In other words,
	/// it stops after <c>frequency</c> times <c>max_empty_searches</c> of real-time operation. If not set, a datafeed with no
	/// end time that sees no data remains started until it is explicitly stopped. By default, it is not set.
	/// </para>
	/// </summary>
	public PutDatafeedRequestDescriptor MaxEmptySearches(int? maxEmptySearches)
	{
		MaxEmptySearchesValue = maxEmptySearches;
		return Self;
	}

	/// <summary>
	/// <para>
	/// The Elasticsearch query domain-specific language (DSL). This value corresponds to the query object in an
	/// Elasticsearch search POST body. All the options that are supported by Elasticsearch can be used, as this
	/// object is passed verbatim to Elasticsearch.
	/// </para>
	/// </summary>
	public PutDatafeedRequestDescriptor Query(Elastic.Clients.Elasticsearch.QueryDsl.Query? query)
	{
		QueryDescriptor = null;
		QueryDescriptorAction = null;
		QueryValue = query;
		return Self;
	}

	public PutDatafeedRequestDescriptor Query(Elastic.Clients.Elasticsearch.QueryDsl.QueryDescriptor descriptor)
	{
		QueryValue = null;
		QueryDescriptorAction = null;
		QueryDescriptor = descriptor;
		return Self;
	}

	public PutDatafeedRequestDescriptor Query(Action<Elastic.Clients.Elasticsearch.QueryDsl.QueryDescriptor> configure)
	{
		QueryValue = null;
		QueryDescriptor = null;
		QueryDescriptorAction = configure;
		return Self;
	}

	/// <summary>
	/// <para>
	/// The number of seconds behind real time that data is queried. For example, if data from 10:04 a.m. might
	/// not be searchable in Elasticsearch until 10:06 a.m., set this property to 120 seconds. The default
	/// value is randomly selected between <c>60s</c> and <c>120s</c>. This randomness improves the query performance
	/// when there are multiple jobs running on the same node.
	/// </para>
	/// </summary>
	public PutDatafeedRequestDescriptor QueryDelay(Elastic.Clients.Elasticsearch.Duration? queryDelay)
	{
		QueryDelayValue = queryDelay;
		return Self;
	}

	/// <summary>
	/// <para>
	/// Specifies runtime fields for the datafeed search.
	/// </para>
	/// </summary>
	public PutDatafeedRequestDescriptor RuntimeMappings(Func<FluentDescriptorDictionary<Elastic.Clients.Elasticsearch.Field, Elastic.Clients.Elasticsearch.Mapping.RuntimeFieldDescriptor>, FluentDescriptorDictionary<Elastic.Clients.Elasticsearch.Field, Elastic.Clients.Elasticsearch.Mapping.RuntimeFieldDescriptor>> selector)
	{
		RuntimeMappingsValue = selector?.Invoke(new FluentDescriptorDictionary<Elastic.Clients.Elasticsearch.Field, Elastic.Clients.Elasticsearch.Mapping.RuntimeFieldDescriptor>());
		return Self;
	}

	/// <summary>
	/// <para>
	/// Specifies scripts that evaluate custom expressions and returns script fields to the datafeed.
	/// The detector configuration objects in a job can contain functions that use these script fields.
	/// </para>
	/// </summary>
	public PutDatafeedRequestDescriptor ScriptFields(Func<FluentDescriptorDictionary<string, Elastic.Clients.Elasticsearch.ScriptFieldDescriptor>, FluentDescriptorDictionary<string, Elastic.Clients.Elasticsearch.ScriptFieldDescriptor>> selector)
	{
		ScriptFieldsValue = selector?.Invoke(new FluentDescriptorDictionary<string, Elastic.Clients.Elasticsearch.ScriptFieldDescriptor>());
		return Self;
	}

	/// <summary>
	/// <para>
	/// The size parameter that is used in Elasticsearch searches when the datafeed does not use aggregations.
	/// The maximum value is the value of <c>index.max_result_window</c>, which is 10,000 by default.
	/// </para>
	/// </summary>
	public PutDatafeedRequestDescriptor ScrollSize(int? scrollSize)
	{
		ScrollSizeValue = scrollSize;
		return Self;
	}

	protected override void Serialize(Utf8JsonWriter writer, JsonSerializerOptions options, IElasticsearchClientSettings settings)
	{
		writer.WriteStartObject();
		if (AggregationsValue is not null)
		{
			writer.WritePropertyName("aggregations");
			JsonSerializer.Serialize(writer, AggregationsValue, options);
		}

		if (ChunkingConfigDescriptor is not null)
		{
			writer.WritePropertyName("chunking_config");
			JsonSerializer.Serialize(writer, ChunkingConfigDescriptor, options);
		}
		else if (ChunkingConfigDescriptorAction is not null)
		{
			writer.WritePropertyName("chunking_config");
			JsonSerializer.Serialize(writer, new Elastic.Clients.Elasticsearch.MachineLearning.ChunkingConfigDescriptor(ChunkingConfigDescriptorAction), options);
		}
		else if (ChunkingConfigValue is not null)
		{
			writer.WritePropertyName("chunking_config");
			JsonSerializer.Serialize(writer, ChunkingConfigValue, options);
		}

		if (DelayedDataCheckConfigDescriptor is not null)
		{
			writer.WritePropertyName("delayed_data_check_config");
			JsonSerializer.Serialize(writer, DelayedDataCheckConfigDescriptor, options);
		}
		else if (DelayedDataCheckConfigDescriptorAction is not null)
		{
			writer.WritePropertyName("delayed_data_check_config");
			JsonSerializer.Serialize(writer, new Elastic.Clients.Elasticsearch.MachineLearning.DelayedDataCheckConfigDescriptor(DelayedDataCheckConfigDescriptorAction), options);
		}
		else if (DelayedDataCheckConfigValue is not null)
		{
			writer.WritePropertyName("delayed_data_check_config");
			JsonSerializer.Serialize(writer, DelayedDataCheckConfigValue, options);
		}

		if (FrequencyValue is not null)
		{
			writer.WritePropertyName("frequency");
			JsonSerializer.Serialize(writer, FrequencyValue, options);
		}

		if (HeadersValue is not null)
		{
			writer.WritePropertyName("headers");
			JsonSerializer.Serialize(writer, HeadersValue, options);
		}

		if (IndicesValue is not null)
		{
			writer.WritePropertyName("indices");
			JsonSerializer.Serialize(writer, IndicesValue, options);
		}

		if (IndicesOptionsDescriptor is not null)
		{
			writer.WritePropertyName("indices_options");
			JsonSerializer.Serialize(writer, IndicesOptionsDescriptor, options);
		}
		else if (IndicesOptionsDescriptorAction is not null)
		{
			writer.WritePropertyName("indices_options");
			JsonSerializer.Serialize(writer, new Elastic.Clients.Elasticsearch.IndicesOptionsDescriptor(IndicesOptionsDescriptorAction), options);
		}
		else if (IndicesOptionsValue is not null)
		{
			writer.WritePropertyName("indices_options");
			JsonSerializer.Serialize(writer, IndicesOptionsValue, options);
		}

		if (JobIdValue is not null)
		{
			writer.WritePropertyName("job_id");
			JsonSerializer.Serialize(writer, JobIdValue, options);
		}

		if (MaxEmptySearchesValue.HasValue)
		{
			writer.WritePropertyName("max_empty_searches");
			writer.WriteNumberValue(MaxEmptySearchesValue.Value);
		}

		if (QueryDescriptor is not null)
		{
			writer.WritePropertyName("query");
			JsonSerializer.Serialize(writer, QueryDescriptor, options);
		}
		else if (QueryDescriptorAction is not null)
		{
			writer.WritePropertyName("query");
			JsonSerializer.Serialize(writer, new Elastic.Clients.Elasticsearch.QueryDsl.QueryDescriptor(QueryDescriptorAction), options);
		}
		else if (QueryValue is not null)
		{
			writer.WritePropertyName("query");
			JsonSerializer.Serialize(writer, QueryValue, options);
		}

		if (QueryDelayValue is not null)
		{
			writer.WritePropertyName("query_delay");
			JsonSerializer.Serialize(writer, QueryDelayValue, options);
		}

		if (RuntimeMappingsValue is not null)
		{
			writer.WritePropertyName("runtime_mappings");
			JsonSerializer.Serialize(writer, RuntimeMappingsValue, options);
		}

		if (ScriptFieldsValue is not null)
		{
			writer.WritePropertyName("script_fields");
			JsonSerializer.Serialize(writer, ScriptFieldsValue, options);
		}

		if (ScrollSizeValue.HasValue)
		{
			writer.WritePropertyName("scroll_size");
			writer.WriteNumberValue(ScrollSizeValue.Value);
		}

		writer.WriteEndObject();
	}
}